﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Skyhook.Core;
using Microsoft.Xna.Framework;

namespace Skyhook.Isometry
{
    internal class WorldOnScreenView : IOnScreenView
    {
        WorldTileMap TileMap = null;
        int Width = 0;
        int Height = 0;

        int CurrentDataNum = 0;
        int CurrentObjectNum = 0;
        int CurrentObjectsCount = 0;
        Point CurrentLeftTop;
        bool FirstObjectGot = false;

        Point pLeftTop;

        Point[] VisualizeData = null;

        public void OnCameraChange(Point centerposition, Point lefttopposition)
        {
            pLeftTop = lefttopposition;
        }

        private void CalculateVisualizeData(int viewwidth, int viewheight,int tilewidth,int tileheight)
        {
            int totalrows = (viewheight / tileheight + 4) * 2 + 1;
            int tilesinrow = viewwidth / tilewidth + 4;
            VisualizeData = new Point[tilesinrow * totalrows];

            int posx = -2;
            int posy = 0;
            int arraypos = 0;

            int startx = posx;
            int starty = posy;
            bool ytochange = false;

            for (int i = 0; i < totalrows; i++)
            {
                for (int j = 0; j < tilesinrow; j++)
                {
                    VisualizeData[arraypos] = new Point(posx, posy);
                    posx += 1;
                    posy -= 1;
                    arraypos++;
                }
                if (ytochange)
                {
                    starty += 1;
                    posx = startx;
                    posy = starty;
                    ytochange = false;
                }
                else
                {
                    startx += 1;
                    posx = startx;
                    posy = starty;
                    ytochange = true;
                }
            }
        }

        internal WorldOnScreenView(World world, int viewwidth, int viewheight, float tilewidth, float tileheight)
        {
            Width = world.Width;
            Height = world.Height;
            TileMap = world.TileMap;

            CalculateVisualizeData(viewwidth, viewwidth, (int)tilewidth, (int)tileheight);
        }

        public IVisual GetFirstVisual()
        {
            CurrentDataNum = 0;

            if (VisualizeData.Length == 0)
            {
                return null;
            }

            CurrentLeftTop = CoordinatesConverter.ConvertScreenToWorldTiles(pLeftTop.X, pLeftTop.Y);

            for(CurrentDataNum = 0; CurrentDataNum < VisualizeData.Length; CurrentDataNum++)
            {
                int x = VisualizeData[CurrentDataNum].X + CurrentLeftTop.X;
                int y = VisualizeData[CurrentDataNum].Y + CurrentLeftTop.Y;
                if (x >= 0 && x < Width && y >= 0 && y < Height)
                {
                    CurrentObjectsCount = TileMap.GetObjectsCountAtTile(x,y);
                    if (CurrentObjectsCount > 0)
                    {
                        CurrentObjectNum = 0;
                        FirstObjectGot = true;
                        return TileMap.GetObjectAtTile(x, y, CurrentObjectNum).Content.Visual;
                    }
                }
            }
            return null;
        }

        public IVisual GetNextVisual()
        {
            if (!FirstObjectGot)
            {
                return null;
            }

            int x = VisualizeData[CurrentDataNum].X + CurrentLeftTop.X;
            int y = VisualizeData[CurrentDataNum].Y + CurrentLeftTop.Y;

            CurrentObjectNum++;

            if (CurrentObjectNum < CurrentObjectsCount)
            {
                return TileMap.GetObjectAtTile(x, y, CurrentObjectNum).Content.Visual;
            }

            CurrentDataNum++;

            for (; CurrentDataNum < VisualizeData.Length; CurrentDataNum++)
            {
                x = VisualizeData[CurrentDataNum].X + CurrentLeftTop.X;
                y = VisualizeData[CurrentDataNum].Y + CurrentLeftTop.Y;
                if (x >= 0 && x < Width && y >= 0 && y < Height)
                {
                    CurrentObjectsCount = TileMap.GetObjectsCountAtTile(x, y);
                    if (CurrentObjectsCount > 0)
                    {
                        CurrentObjectNum = 0;
                        return TileMap.GetObjectAtTile(x, y, CurrentObjectNum).Content.Visual;
                    }
                }
            }

            return null;
        }

        public Point LeftTop
        {
            get
            {
                return pLeftTop;
            }
        }
    }
}
